package com.turing.post.tuxedo.util;

import java.io.Reader;
import java.io.StringReader;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.Date;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;

import com.turing.post.util.HexDump;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;

/**
 * XML报文解析辅助类
 * 
 * @author yxb
 * 
 */
public final class TransXmlHelper {
	public static final String XML_CHARSET = "gb18030";
	public static final String XML_DEFAULT_TRANKEY = "00000000";

	public static final String XML_NODE_TransRequest = "TransRequest";
	public static final String XML_NODE_TransResponse = "TransResponse";

	public static final String XML_NODE_TranCode = "TranCode";
	public static final String XML_NODE_MerchantNo = "MerchantNo";
	public static final String XML_NODE_TranMac = "TranMac";

	public static final String XML_NODE_ReqBody = "ReqBody";
	public static final String XML_NODE_RespBody = "RespBody";
	public static final String XML_NODE_RespCode = "RespCode";
	public static final String XML_NODE_RespErrMsg = "RespErrMsg";

	public static final String XML_NODE_Expired = "Expired";
	public static final String XML_NODE_Balance = "Balance";

	public static final String XML_NODE_CardNo = "CardNo";
	public static final String XML_NODE_Track2 = "Track2";
	public static final String XML_NODE_Track3 = "Track3";
	public static final String XML_NODE_Passwd = "Passwd";
	public static final String XML_NODE_NewPwd = "NewPwd";
	public static final String XML_NODE_Amount = "Amount";

	public static final String XML_NODE_TotalAmount = "TotalAmount";
	public static final String XML_NODE_CardNum = "CardNum";
	public static final String XML_NODE_Paid = "Paid";
	public static final String XML_NODE_Card = "Card";

	public static final String XML_NODE_OtherPaidAmount = "OtherPaidAmount";

	public static final String XML_NODE_MemberShip = "MemberShip";
	public static final String XML_NODE_ScorePaidAmount = "ScorePaidAmount";

	public static final String XML_NODE_BrchNo = "BrchNo";
	public static final String XML_NODE_BrchName = "BrchName";
	public static final String XML_NODE_TellerNo = "TellerNo";
	public static final String XML_NODE_TellerName = "TellerName";

	public static final String XML_NODE_PosNo = "PosNo";
	public static final String XML_NODE_PosSeqNo = "PosSeqNo";
	public static final String XML_NODE_PosSettBatchNo = "PosSettBatchNo";

	public static final String XML_NODE_TranDate = "TranDate";
	public static final String XML_NODE_TranTime = "TranTime";

	public static final String XML_NODE_Additional = "Additional";
	public static final String XML_NODE_Asbtract = "Asbtract";
	public static final String XML_NODE_SaleOrder = "SaleOrder";
	public static final String XML_NODE_SaleOrderNo = "SaleOrderNo";
	public static final String XML_NODE_BusinessDetailNum = "BusinessDetailNum";
	public static final String XML_NODE_BusinessDetail = "BusinessDetail";
	public static final String XML_NODE_BusinessType = "BusinessType";
	public static final String XML_NODE_BusinessAmount = "BusinessAmount";

	public static final String XML_NODE_ReqSeqNo = "ReqSeqNo";
	public static final String XML_NODE_AckSeqNo = "AckSeqNo";
	public static final String XML_NODE_ScoreAmount = "ScoreAmount";
	public static final String XML_NODE_FactScorePaidAmount = "FactScorePaidAmount";
	public static final String XML_NODE_Score = "Score";
	public static final String XML_NODE_FeeRatio = "FeeRatio";
	public static final String XML_NODE_TotalFee = "TotalFee";

	public static final String XML_NODE_DebitAmount = "DebitAmount";
	public static final String XML_NODE_DebitCount = "DebitCount";
	public static final String XML_NODE_CreditAmount = "CreditAmount";
	public static final String XML_NODE_CreditCount = "CreditCount";

	public static final String XML_NODE_OrigPosNo = "OrigPosNo";
	public static final String XML_NODE_OrigPosSettBatchNo = "OrigPosSettBatchNo";
	public static final String XML_NODE_OrigPosSeqNo = "OrigPosSeqNo";
	public static final String XML_NODE_OrigTranDate = "OrigTranDate";
	public static final String XML_NODE_OrigReqSeqNo = "OrigReqSeqNo";
	public static final String XML_NODE_OrigAckSeqNo = "OrigAckSeqNo";
	public static final String XML_NODE_Reason = "Reason";

	public static final String XML_NODE_DepositLimit = "DepositLimit";
	public static final String XML_NODE_Fee = "Fee";
	public static final String XML_NODE_PaidCountLeft = "PaidCountLeft";
	public static final String XML_NODE_AvailBalance = "AvailBalance";

	public static final String XML_NODE_BsTypeCount = "BsTypeCount";
	public static final String XML_NODE_BsType = "BsType";
	public static final String XML_NODE_BsTypeId = "BsTypeId";
	public static final String XML_NODE_BsTypeName = "BsTypeName";

	/**
	 * 获得有效期字符串
	 * 
	 * @param expired
	 * @return
	 */
	public static String getExpired(Date expired) {
		if (expired == null)
			return "00000000";
		else
			return PCPSUtil.getPackedYMDString(expired);
	}

	/**
	 * 根据字节数组,返回org.jdom2.Document
	 * 
	 * @param ibuf
	 * @return
	 * @throws Exception
	 */
	public static Document getXmlDocumentFromBuffer(byte[] ibuf)
			throws PCPSApplicationException {
		try {
			PCPSUtil.Log(HexDump.EOL + "PCPS request data LEN " + ibuf.length
					+ HexDump.EOL + HexDump.dump(ibuf, 0, 0));
			SAXBuilder builder = new SAXBuilder();
			String reqXml = new String(ibuf, Charset.forName(XML_CHARSET))
					.trim();
			Reader in = new StringReader(reqXml);
			return builder.build(in);
		} catch (Exception ex) {
			PCPSUtil.Log("getXmlDocumentFromBuffer error!", ex);
			ParaseException.TransParamException("getXmlDocumentFromBuffer error!");
		}
		return null;
	}

	/**
	 * 增加字符串
	 * 
	 * @param parent
	 * @param nodeName
	 * @param nodeValue
	 */
	public static void addStringElement(Element parent, String nodeName,
			String nodeValue) {
		if (PCPSUtil.isEmpty(nodeValue))
			return;
		Element el = new Element(nodeName);
		el.addContent(nodeValue);
		parent.addContent(el);
	}

	/**
	 * 返回必须存在的字符串
	 * 
	 * @param root
	 * @param nodeName
	 * @return
	 * @throws Exception
	 */
	public static String getMandatoryString(Element root, String nodeName)
			throws PCPSApplicationException {
		Element node = root.getChild(nodeName);
		if (node == null)
			ParaseException.TransParamException(nodeName + " 不存在!");
		String nodeval = node.getTextTrim();
		if (PCPSUtil.isEmpty(nodeval))
			ParaseException.TransParamException(nodeName + " 为NULL!");
		return nodeval;
	}

	/**
	 * 获取可选字符串
	 * 
	 * @param root
	 * @param nodeName
	 * @return
	 */
	public static String getOptionalString(Element root, String nodeName) {
		Element node = root.getChild(nodeName);
		return (node != null) ? node.getTextTrim() : "";
	}

	/**
	 * 解析数字
	 * 
	 * @param root
	 * @param nodeName
	 * @return
	 * @throws Exception
	 */
	public static BigInteger getInteger(Element root, String nodeName)
			throws PCPSApplicationException {
		String str = getMandatoryString(root, nodeName);
		BigInteger ival = BigInteger.ZERO;

		try {
			ival = new BigInteger(str);
		} catch (Exception e) {
			ParaseException.TransParamException(nodeName + " 数字非法!");
		}

		return ival;
	}
}
